﻿


Public Class ZipNode
    Inherits KryptonTreeNode
    Implements IContainable, ISettable
    Private Shared ZipsCount As Integer = 0
    Public Sub New(ByVal type As ZipType)
        MyBase.New()
        Control.CheckForIllegalCrossThreadCalls = False
        Me.Type = type
        Me.Text = "Zip File " & CStr(ZipsCount)
        ZipsCount += 1
        Me.LongText = StringFromSize(_Size)
        _EntrySettings = New EntrySettings With {.Method = Zip.CompressionMethod.None, .Level = Zlib.CompressionLevel.None}
        _ZipSettings = New ZipSettings
        _Maker = New InnerZipMaker(Me)
    End Sub

    '''''''''''''''''''''''''''''''''''''Fields''''''''''''''''''''''''''''''''''''
    Private _Type As ZipType
    Public Property Type As ZipType
        Get
            Return _Type
        End Get
        Set(value As ZipType)
            _Type = value
            Me.ImageKey = _Type.ImageKey
            Me.SelectedImageKey = _Type.ImageKey
        End Set
    End Property
    Private _IsRootZipNode As Boolean
    Public Property IsRootZipNode As Boolean
        Get
            Return _IsRootZipNode
        End Get
        Set(value As Boolean)
            _IsRootZipNode = value
        End Set
    End Property
    'Replace ZipNode With Its Compressed Zip Files Nodes.
    Public Sub Replace(ByVal fnl As List(Of FileNode))
        Dim cont As IContainable = CType(Me.Parent, IContainable)
        For Each fn As FileNode In fnl
            cont.AddFileNode(fn)
            fn.EntrySettings.CopyFrom(Me.EntrySettings)
        Next
        Me.Delete()
    End Sub

    '''''''''''''''''''''''''''''''''''''IConatinable''''''''''''''''''''''''''''''''''''
    Private _Size As Long
    Public ReadOnly Property Size As Long Implements IContainable.Size
        Get
            Return _Size
        End Get
    End Property
    Public Sub UpdateSize(ByVal sizediff As Long) Implements IContainable.UpdateSize
        _Size += sizediff
        _ZipSettings.Splitting.Size = _Size
        Me.LongText = StringFromSize(_Size)
        If Me.Parent IsNot Nothing Then
            CType(Me.Parent, IContainable).UpdateSize(sizediff)
        End If
    End Sub

    Public ReadOnly Property FilesNodes As List(Of FileNode) Implements IContainable.FilesNodes
        Get
            Dim fnl As New List(Of FileNode)
            For Each n As KryptonTreeNode In Me.Nodes
                If TypeOf n Is FileNode Then
                    fnl.Add(CType(n, FileNode))
                End If
            Next
            Return fnl
        End Get
    End Property
    Public ReadOnly Property FoldersNodes As List(Of FolderNode) Implements IContainable.FoldersNodes
        Get
            Dim fnl As New List(Of FolderNode)
            For Each n As KryptonTreeNode In Me.Nodes
                If TypeOf n Is FolderNode Then
                    fnl.Add(CType(n, FolderNode))
                End If
            Next
            Return fnl
        End Get
    End Property
    Public ReadOnly Property ZipNodes As List(Of ZipNode) Implements IContainable.ZipNodes
        Get
            Dim znl As New List(Of ZipNode)
            For Each zn As KryptonTreeNode In Me.Nodes
                If TypeOf zn Is ZipNode Then
                    znl.Add(CType(zn, ZipNode))
                End If
            Next
            Return znl
        End Get
    End Property
    Public ReadOnly Property InnerZipNodes As List(Of ZipNode) Implements IContainable.InnerZipNodes
        Get
            Dim iznl As New List(Of ZipNode)
            iznl.AddRange(Me.ZipNodes)
            For Each zn As ZipNode In Me.ZipNodes
                iznl.AddRange(zn.InnerZipNodes)
            Next
            For Each fn As FolderNode In Me.FoldersNodes
                iznl.AddRange(fn.InnerZipNodes)
            Next
            Return iznl
        End Get
    End Property
    Public ReadOnly Property InnerFilesNode As List(Of FileNode) Implements IContainable.InnerFilesNode
        Get
            Dim ifn As New List(Of FileNode)
            ifn.AddRange(Me.FilesNodes)
            For Each fn As FolderNode In Me.FoldersNodes
                ifn.AddRange(fn.InnerFilesNode)
            Next
            Return ifn
        End Get
    End Property

    'Nodes Operations :
    Private Function NewZipNodeIndex() As Integer
        If Me.ZipNodes.Count = 0 Then
            Return 0
        Else
            Return Me.Nodes.IndexOf(Me.ZipNodes.Last) + 1
        End If
    End Function
    Private Function NewFolderNodeIndex() As Integer
        If Me.FoldersNodes.Count = 0 Then
            Return 0
        Else
            Return Me.Nodes.IndexOf(Me.FoldersNodes.Last) + 1
        End If
    End Function

    Public Sub AddFileNode(fn As FileNode) Implements IContainable.AddFileNode
        Me.Nodes.Add(fn)
        Me.UpdateSize(fn.Size)
        fn.InheritEntrySettings()
    End Sub
    Public Sub AddFolderNode(fn As FolderNode) Implements IContainable.AddFolderNode
        Me.Nodes.Insert(NewFolderNodeIndex, fn)
        Me.UpdateSize(fn.Size)
        fn.InheritEntrySettings()
        fn.UpdateChildsEntrySettings()
    End Sub
    Public Sub AddZipNode(zn As ZipNode) Implements IContainable.AddZipNode
        Me.Nodes.Insert(NewZipNodeIndex, zn)
        Me.UpdateSize(zn.Size)
        zn.InheritEntrySettings()
        zn.UpdateChildsEntrySettings()
    End Sub

    Public Function Clean() As List(Of String) Implements IContainable.Clean
        Dim filestoremove As New List(Of String)
        For Each fn As FileNode In Me.FilesNodes
            If IO.File.Exists(fn.SourcePath) = False Then
                filestoremove.Add(fn.Delete())
            End If
        Next
        For Each fn As FolderNode In FoldersNodes
            If fn.Size = 0L Then
                fn.Delete()
            Else
                filestoremove.AddRange(fn.Clean())
            End If
        Next
        For Each zn As ZipNode In ZipNodes
            If zn.Size = 0L Then
                zn.Delete()
            Else
                filestoremove.AddRange(zn.Clean())
            End If
        Next
        If Me.Size = 0L Then
            Me.Delete()
        End If
        Return filestoremove
    End Function
    Public Function Clear() As List(Of String) Implements IContainable.Clear
        Dim filestoremove As New List(Of String)
        For Each fn As FileNode In Me.FilesNodes
            filestoremove.Add(fn.Delete())
        Next
        For Each fn As FolderNode In Me.FoldersNodes
            filestoremove.AddRange(fn.Delete())
        Next
        For Each zn As ZipNode In Me.ZipNodes
            filestoremove.AddRange(zn.Delete())
        Next
        Return filestoremove
    End Function
    Public Function Delete() As List(Of String) Implements IContainable.Delete
        Dim filestoremove As New List(Of String)
        For Each fn As FileNode In Me.FilesNodes
            filestoremove.Add(fn.Delete())
        Next
        For Each fn As FolderNode In Me.FoldersNodes
            filestoremove.AddRange(fn.Delete())
        Next
        For Each zn As ZipNode In Me.ZipNodes
            filestoremove.AddRange(zn.Delete())
        Next
        Me.Remove()
        Return filestoremove
    End Function

    '''''''''''''''''''''''''''''''''''''ISettable''''''''''''''''''''''''''''''''''''
    Private _EntrySettings As EntrySettings
    Public ReadOnly Property EntrySettings As EntrySettings Implements ISettable.EntrySettings
        Get
            Return _EntrySettings
        End Get
    End Property
    'Inherit Parent Entry Settings :
    Public Sub InheritEntrySettings() Implements ISettable.InheritEntrySettings
        Dim com As String = Me.EntrySettings.Comment
        If Me.Parent IsNot Nothing Then
            If TypeOf Me.Parent Is FolderNode Then
                Me.EntrySettings.CopyFrom(CType(Me.Parent, FolderNode).EntrySettings)
            ElseIf TypeOf Me.Parent Is ZipNode Then
                Me.EntrySettings.CopyFrom(CType(Me.Parent, ZipNode).ZipSettings.MakeEntrySettings)
            End If
        End If
        Me.EntrySettings.Method = Zip.CompressionMethod.None
        Me.EntrySettings.Level = Zlib.CompressionLevel.None
        Me.EntrySettings.Comment = com
    End Sub
    Public Sub UpdateChildsEntrySettings() Implements IContainable.UpdateChildsEntrySettings
        For Each fn As FileNode In Me.FilesNodes
            fn.InheritEntrySettings()
        Next
        For Each fn As FolderNode In Me.FoldersNodes
            fn.InheritEntrySettings()
            fn.UpdateChildsEntrySettings()
        Next
        For Each zn As ZipNode In Me.ZipNodes
            zn.InheritEntrySettings()
        Next
    End Sub
    'Zip Settingss :
    Private _ZipSettings As ZipSettings
    Public ReadOnly Property ZipSettings As ZipSettings
        Get
            Return _ZipSettings
        End Get
    End Property
    '''''''''''''''''''''''''''''''''''''Inner Zip Maker'''''''''''''''''''''''''''''''
    Private WithEvents _Maker As InnerZipMaker
    Public ReadOnly Property Maker As InnerZipMaker
        Get
            Return _Maker
        End Get
    End Property

    Private Sub _Maker_InnerZipMakerStateChanged(sender As Object, e As InnerZipMakerStateChanged) Handles _Maker.InnerZipMakerStateChanged
        Me.LongText = e.State
        Me.TreeView.Refresh()
        If e.State = "Finished" Then
            Dim replacements As List(Of FileNode) = CType(e.Data, List(Of FileNode))
            RaiseEvent InnerZipNodeCreated(Me, New ZipSavingFinishedEventArgs(Me, replacements))
        End If
    End Sub
    Public Event InnerZipNodeCreated As EventHandler(Of ZipSavingFinishedEventArgs)

End Class





